package org.springblade.modules.platform.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.modules.platform.dto.*;
import org.springblade.modules.platform.entity.*;
import org.springblade.modules.platform.mapper.DeviceTableMapper;
import org.springblade.modules.platform.mapper.EquipmentRuningStateMapper;
import org.springblade.modules.platform.mapper.ProductModelPropertiesMapper;
import org.springblade.modules.platform.mapper.ProductTypeMapper;
import org.springblade.modules.platform.service.IDeviceTableService;
import org.springblade.modules.platform.vo.DeviceTableListVO;
import org.springblade.modules.platform.vo.DeviceTableVO;
import org.springblade.modules.platform.vo.EquipmentRuningStateVO;
import org.springblade.modules.platform.vo.enums.DeviceStatusEnum;
import org.springblade.modules.platform.vo.enums.PlatformStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.secure.utils.AuthUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SYG
 * @since 2022-08-30
 */
@Service
@Slf4j
public class DeviceTableServiceImpl extends ServiceImpl<DeviceTableMapper, DeviceTable> implements IDeviceTableService {
    @Autowired
    ProductTypeMapper productTypeMapper;
    @Autowired
    EquipmentRuningStateMapper equipmentRuningStateMapper;
    @Autowired
    ProductModelPropertiesMapper productModelPropertiesMapper;




    @Override
    public DeviceTableListVO selectDeviceList(DeviceTablePageDTO deviceTablePageDTO) {
        DeviceTableListVO deviceTableListVO = new DeviceTableListVO();

        QueryWrapper<DeviceTable> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DeviceTable::getIsDeleted,0);
        List<DeviceTable> deviceTables = baseMapper.selectList(queryWrapper);
        if(!StringUtils.isEmpty(deviceTablePageDTO.getDeviceName())){
            queryWrapper.lambda().like(DeviceTable::getDeviceName,deviceTablePageDTO.getDeviceName());
        }
        if(!StringUtils.isEmpty(deviceTablePageDTO.getDeviceId())){
            queryWrapper.lambda().like(DeviceTable::getDeviceId,deviceTablePageDTO.getDeviceId());
        }
        if(!StringUtils.isEmpty(deviceTablePageDTO.getProductId())){
            queryWrapper.lambda().eq(DeviceTable::getProductId,deviceTablePageDTO.getProductId());
        }
        if(deviceTablePageDTO.getStatus()!= null){
            queryWrapper.lambda().eq(DeviceTable::getStatus,deviceTablePageDTO.getStatus().getCode());
        }
        if(!StringUtils.isEmpty(deviceTablePageDTO.getAffiliatedInstitutionsCode())){
            queryWrapper.lambda().eq(DeviceTable::getAffiliatedInstitutionsCode,deviceTablePageDTO.getAffiliatedInstitutionsCode());
        }
        Page<DeviceTable> deviceTablePage = baseMapper.selectPage(new Page<>(deviceTablePageDTO.getCurrent(), deviceTablePageDTO.getSize()), queryWrapper);
        long total = deviceTablePage.getTotal();
        deviceTableListVO.setTotal(total);
        if(total>0){
            List<DeviceTable> records = deviceTablePage.getRecords();
            List<DeviceTableVO> collect = records.stream().map(x -> {
                DeviceTableVO deviceTableVO = new DeviceTableVO();
                BeanUtils.copyProperties(x, deviceTableVO);
                deviceTableVO.setStatus(DeviceStatusEnum.getEnum(x.getStatus()));
                deviceTableVO.setPlatformStatus(PlatformStatusEnum.getEnum(x.getPlatformStatus()));
                ProductType productType = productTypeMapper.selectOne(Wrappers.<ProductType>query().lambda().eq(ProductType::getProductId, x.getProductId()).eq(ProductType::getIsDeleted, 0));
                if(productType != null){
                    deviceTableVO.setProductName(productType.getProductName());
                }
                deviceTableVO.setDeviceType(x.getDeviceType());
                return deviceTableVO;
            }).collect(Collectors.toList());
            deviceTableListVO.setDeviceTableVOList(collect);
        }
        if(!CollectionUtils.isEmpty(deviceTables)){
            long count = deviceTables.stream().filter(x -> Objects.equals(x.getStatus(), DeviceStatusEnum.OFFLINE.getCode())).count();
            deviceTableListVO.setOfflineTotal(count);

            long count1 = deviceTables.stream().filter(x -> Objects.equals(x.getStatus(), DeviceStatusEnum.ONLINE.getCode())).count();
            deviceTableListVO.setOnlineTotal(count1);
        }
        return deviceTableListVO;
    }

    @Override
    public DeviceTableVO selectDeviceById(String deviceId) {
        DeviceTable deviceTable = baseMapper.selectOne(Wrappers.<DeviceTable>query().lambda().eq(DeviceTable::getDeviceId, deviceId).eq(DeviceTable::getIsDeleted, 0));
        if(deviceTable == null){
            return null;
        }
        DeviceTableVO deviceTableVO = new DeviceTableVO();
        BeanUtils.copyProperties(deviceTable, deviceTableVO);
        deviceTableVO.setStatus(DeviceStatusEnum.getEnum(deviceTable.getStatus()));
        deviceTableVO.setPlatformStatus(PlatformStatusEnum.getEnum(deviceTable.getPlatformStatus()));
        ProductType productType = productTypeMapper.selectOne(Wrappers.<ProductType>query().lambda().eq(ProductType::getProductId, deviceTable.getProductId()).eq(ProductType::getIsDeleted, 0));
        if(productType != null){
            deviceTableVO.setProductName(productType.getProductName());
        }
        deviceTableVO.setTenantId(AuthUtil.getTenantId());
        return deviceTableVO;
    }

    @Override
    public void insertDevice(DeviceTableDTO deviceTableDTO) {

        DeviceTable deviceTable = new DeviceTable();
        BeanUtils.copyProperties(deviceTableDTO, deviceTable);
        deviceTable.setStatus(DeviceStatusEnum.OFFLINE.getCode());
        deviceTable.setPlatformStatus(PlatformStatusEnum.DISABLED.getCode());
        deviceTable.setCreateUser(AuthUtil.getUserId());
        deviceTable.setTenantId(AuthUtil.getTenantId());
        deviceTable.setInsertTime(System.currentTimeMillis());
        deviceTable.setUpdateTime(System.currentTimeMillis());
        deviceTable.setIsDeleted(0);
        int insert = baseMapper.insert(deviceTable);
        if(insert>0){
    /*        List<String> tableNameList = equipmentRuningStateMapper.getTableNameList();*/
            String tableName = "equipment_runing_state_"+deviceTableDTO.getDeviceId();
            equipmentRuningStateMapper.createTable(deviceTableDTO.getDeviceId());

        }

    }

    @Override
    public void updateDevice(DeviceTableDTO deviceTableDTO) {
        DeviceTable deviceTable = baseMapper.selectOne(Wrappers.<DeviceTable>query().lambda()
                .eq(DeviceTable::getDeviceId, deviceTableDTO.getDeviceId())
                .eq(DeviceTable::getIsDeleted, 0));
        BeanUtils.copyProperties(deviceTableDTO,deviceTable);
        deviceTable.setStatus(DeviceStatusEnum.OFFLINE.getCode());
        deviceTable.setPlatformStatus(PlatformStatusEnum.ENABLE.getCode());
        deviceTable.setCreateUser(AuthUtil.getUserId());
        deviceTable.setTenantId(AuthUtil.getTenantId());
        deviceTable.setUpdateTime(System.currentTimeMillis());
        deviceTable.setIsDeleted(0);
        baseMapper.updateById(deviceTable);
    }

    @Override
    public void removeDevice(String[] deviceIds) {
        List<DeviceTable> deviceTables = baseMapper.selectList(Wrappers.<DeviceTable>query().lambda().in(DeviceTable::getDeviceId, deviceIds).eq(DeviceTable::getIsDeleted, 0));
        if(!CollectionUtils.isEmpty(deviceTables)){
            deviceTables.forEach(x->{
                x.setIsDeleted(1);
                x.setUpdateTime(System.currentTimeMillis());
                baseMapper.updateById(x);
            });
        }
    }

    @Override
    public void updateStatus(UpdateDeviceStatusDTO updateDeviceStatusDTO) {
        DeviceTable deviceTable = baseMapper.selectOne(Wrappers.<DeviceTable>query().lambda()
                .eq(DeviceTable::getDeviceId, updateDeviceStatusDTO.getDeviceId())
                .eq(DeviceTable::getIsDeleted, 0));
        deviceTable.setPlatformStatus(updateDeviceStatusDTO.getPlatformStatus().getCode());
        baseMapper.updateById(deviceTable);
    }

    @Override
    public List<EquipmentRuningStateVO> equipmentRuningState(String equipmentId) {
        List<EquipmentRuningStateVO> map = new ArrayList<>();
        DeviceTable detail = baseMapper.selectOne(new QueryWrapper<DeviceTable>().lambda()
                .eq(DeviceTable::getDeviceId, equipmentId)
                .eq(DeviceTable::getIsDeleted,0));

        ProductModelProperties one = productModelPropertiesMapper.selectOne(new QueryWrapper<ProductModelProperties>().lambda()
                .eq(ProductModelProperties::getProductId, detail.getProductId()));
        List<EquipmentRuningState> list = equipmentRuningStateMapper.selectList(Wrappers.<EquipmentRuningState>query().lambda()
                .eq(EquipmentRuningState::getEquipmentId, equipmentId));
        log.info("最新状态为:{}",list);
        JSONArray propertiesjson = JSONArray.parseArray(one.getPropertiesJson());
        for(Object s:propertiesjson){
            JSONObject o1 = (JSONObject) s;
            String id = o1.get("id").toString();
            String name = o1.get("name").toString();
            JSONObject valueType = (JSONObject)o1.get("valueType");
            EquipmentRuningStateVO equipmentRuningStateVO = new EquipmentRuningStateVO();
            equipmentRuningStateVO.setEquipmentId(equipmentId);
            Optional<EquipmentRuningState> id1 = list.stream().filter(x -> x.getPropertieId().equals(id)).findFirst();
            log.info("最新状态为:{}",id1);
            if(id1.isPresent()){
                EquipmentRuningState equipmentRuningState = id1.get();
                log.info("过滤后最新状态为:{}",equipmentRuningState);
                String jsonText = equipmentRuningState.getJsonText();
                JSONObject jsonObject = JSONObject.parseObject(jsonText);
                String string = valueType.get("type").toString();
                log.info("type:{}",string);
                if(string.equals("enum")){
                    JSONArray elements = (JSONArray)valueType.get("elements");
                    log.info("type:{}",elements);
                    String elementKey = jsonObject.get(equipmentRuningState.getPropertieId()).toString();
                    Optional<Object> text = elements.stream().filter(l -> ((JSONObject) l).get("text").toString().equalsIgnoreCase(elementKey)).findFirst();
                    if(text.isPresent()){
                        log.info("text:{}",text);
                        JSONObject o = (JSONObject)text.get();
                        String string1 = o.get("value").toString();
                        jsonObject.put(equipmentRuningState.getPropertieId(),string1);
                        equipmentRuningStateVO.setJsonText(JSONObject.toJSONString(jsonObject));
                    }
                }else {
                    equipmentRuningStateVO.setJsonText(JSONObject.toJSONString(jsonObject));
                }
                equipmentRuningStateVO.setInsertTime(equipmentRuningState.getInsertTime());
                equipmentRuningStateVO.setUpdateTime(equipmentRuningState.getUpdateTime());
                equipmentRuningStateVO.setEquipmentId(equipmentRuningState.getEquipmentId());
                log.info("equipmentRuningStateVO:{}",equipmentRuningStateVO);
            }

            if(valueType.containsKey("properties")){
                Object o = valueType.get("properties");
                JSONArray jsonArray = (JSONArray)o;
                if(jsonArray.size()!=0){
                    Object o2 = jsonArray.get(0);
                    JSONObject o3 = (JSONObject) o2;
                    if(o3.containsKey("valueType")){
                        Object o4 = o3.get("valueType");
                        JSONObject o5 = (JSONObject)o4;
                        if(o5!=null&&o5.containsKey("unit")){
                            equipmentRuningStateVO.setUnit(o5.get("unit").toString());
                        }
                    }
                }
            }else if(valueType.containsKey("unit")){
                equipmentRuningStateVO.setUnit(valueType.get("unit").toString());
            }
            equipmentRuningStateVO.setPropertieId(id);
            equipmentRuningStateVO.setPropertieName(name);
            map.add(equipmentRuningStateVO);
        }
        return map;
    }

    @Override
    public DeviceTableListVO selectListBox(DeviceTablePageDTO deviceTablePageDTO) {


        DeviceTableListVO deviceTableListVO = new DeviceTableListVO();

        QueryWrapper<DeviceTable> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DeviceTable::getIsDeleted,0)
                .eq(DeviceTable::getPlatformStatus,PlatformStatusEnum.ENABLE.getCode());

        if(!StringUtils.isEmpty(deviceTablePageDTO.getDeviceName())){
            queryWrapper.lambda().like(DeviceTable::getDeviceName,deviceTablePageDTO.getDeviceName());
        }

        Page<DeviceTable> deviceTablePage = baseMapper.selectPage(new Page<>(deviceTablePageDTO.getCurrent(), deviceTablePageDTO.getSize()), queryWrapper);
        long total = deviceTablePage.getTotal();
        deviceTableListVO.setTotal(total);
        if(total>0){
            List<DeviceTable> records = deviceTablePage.getRecords();
            List<DeviceTableVO> collect = records.stream().map(x -> {
                DeviceTableVO deviceTableVO = new DeviceTableVO();
                BeanUtils.copyProperties(x, deviceTableVO);
                deviceTableVO.setStatus(DeviceStatusEnum.getEnum(x.getStatus()));
                deviceTableVO.setPlatformStatus(PlatformStatusEnum.getEnum(x.getPlatformStatus()));
                ProductType productType = productTypeMapper.selectOne(Wrappers.<ProductType>query().lambda().eq(ProductType::getProductId, x.getProductId()).eq(ProductType::getIsDeleted, 0));
                if(productType != null){
                    deviceTableVO.setProductName(productType.getProductName());
                }
                return deviceTableVO;
            }).collect(Collectors.toList());
            deviceTableListVO.setDeviceTableVOList(collect);
        }
        return deviceTableListVO;
    }

    @Override
    public List<DeviceTableVO> selectDeviceByAffiliatedInstitutionsCode(List<Integer> collect1) {

        List<DeviceTable> deviceTables = baseMapper.selectList(Wrappers.<DeviceTable>query().lambda()
                .in(DeviceTable::getAffiliatedInstitutionsCode, collect1)
                .eq(DeviceTable::getPlatformStatus, PlatformStatusEnum.ENABLE.getCode())
                .eq(DeviceTable::getIsDeleted, 0));
        if(!CollectionUtils.isEmpty(deviceTables)){
            List<DeviceTableVO> collect = deviceTables.stream().map(x -> {
                DeviceTableVO deviceTableVO = new DeviceTableVO();
                BeanUtils.copyProperties(x, deviceTableVO);
                deviceTableVO.setStatus(DeviceStatusEnum.getEnum(x.getStatus()));
                deviceTableVO.setPlatformStatus(PlatformStatusEnum.getEnum(x.getPlatformStatus()));
                return deviceTableVO;

            }).collect(Collectors.toList());
            return collect;
        }


        return null;
    }


}
